import os
from typing import Optional
import redis.asyncio as redis
from fastmcp import FastMCP


class RedisServer:
    """
    Redis core operations with connection pooling and bulk support.
    """

    def __init__(
        self,
        host: Optional[str] = None,
        port: Optional[int] = None,
        db: Optional[int] = None,
        password: Optional[str] = None,
        username: Optional[str] = None,
        decode_responses: bool = True,
        max_connections: int = 20,
    ):
        """
        Initialize config.
        """
        self.host = host or os.environ.get("REDIS_HOST", "localhost")
        self.port = port or int(os.environ.get("REDIS_PORT", "6379"))
        self.db = db or int(os.environ.get("REDIS_DB", "0"))
        self.password = password or os.environ.get("REDIS_PASSWORD")
        self.username = username or os.environ.get("REDIS_USERNAME")
        self.decode_responses = decode_responses
        self.max_connections = max_connections
        self.pool = None

    # @staticmethod
    # def _serialize_result(result: Any) -> Any:
    #     """Convert Redis result to JSON-serializable format."""
    #     if isinstance(result, bool):
    #         return result
    #     elif result is None:
    #         return None
    #     elif isinstance(result, (list, dict)):
    #         return result
    #     else:
    #         return str(result)

    async def get_connection(self):
        """Get a Redis client from the connection pool."""
        if not self.pool:
            await self.initialize()
        return redis.Redis(connection_pool=self.pool)

    async def close(self) -> None:
        """Close the connection."""
        if self.pool:
            await self.pool.disconnect()
            self.pool = None

    async def initialize(self):
        """Initialize the connection pool."""
        if self.pool is None:
            self.pool = redis.ConnectionPool(
                host=self.host,
                port=self.port,
                db=self.db,
                password=self.password,
                username=self.username,
                decode_responses=self.decode_responses,
                max_connections=self.max_connections,
            )


redis_server = None

app = FastMCP("Redis Fast MCP Server")


def register_tools():
    from tools.get import get_tool
    from tools.set import set_tool
    from tools.scan import scan_tool

    app.tool()(get_tool)
    app.tool()(set_tool)
    app.tool()(scan_tool)


register_tools()


if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser(description="Redis MCP Server")
    parser.add_argument(
        "--transport",
        default="sse",
        choices=["stdio", "sse", "http", "streamable-http"],
        help="MCP Transport type",
    )
    parser.add_argument("--host", default="localhost", help="Redis host")
    parser.add_argument("--port", default=6379, type=int, help="Redis port")
    parser.add_argument("--db", type=int, default=0, help="Redis database")
    parser.add_argument("--username", help="Redis username")
    parser.add_argument("--password", help="Redis password")
    args = parser.parse_args()

    redis_server = RedisServer(
        host=args.host,
        port=args.port,
        db=args.db,
        password=args.password,
        username=args.username,
    )

    import tools.get
    import tools.set
    import tools.scan

    tools.get.redis_server = redis_server
    tools.set.redis_server = redis_server
    tools.scan.redis_server = redis_server

    if args.transport == "stdio":
        app.run(transport="stdio")
    elif args.transport == "sse":
        app.run(transport="sse", port=3334)
    elif args.transport in ["http", "streamable-http"]:
        app.run(transport="http", port=8000)
    else:
        raise ValueError(f"Unsupported transport: {args.transport}")
